<?php
/**
 * Class that encapsulates the file-upload internals
 */
class Service_qqFileUploader {
	private $allowedExtensions;
	private $sizeLimit;
	private $file;
	private $uploadName;

	/**
	 * @param array $allowedExtensions; defaults to an empty array
	 * @param int $sizeLimit; defaults to the server's upload_max_filesize setting
	 */
	function __construct(array $allowedExtensions = null, $sizeLimit = null){
		if($allowedExtensions===null) {
			$allowedExtensions = array();
		}
		if($sizeLimit===null) {
			$sizeLimit = $this->toBytes(ini_get('upload_max_filesize'));
		}
		 
		$allowedExtensions = array_map("strtolower", $allowedExtensions);

		$this->allowedExtensions = $allowedExtensions;
		$this->sizeLimit = $sizeLimit;

		$this->checkServerSettings();

		if (strpos(strtolower($_SERVER['CONTENT_TYPE']), 'multipart/') === 0) {
			$this->file = new Service_qqUploadedFileForm();
		} 
		else {
			$this->file = new Service_qqUploadedFileXhr();
		}
	}

	/**
	 * Get the name of the uploaded file
	 * @return string
	 */
	public function getUploadName(){
		if( isset( $this->uploadName ) )
			return $this->uploadName;
	}

	/**
	 * Get the original filename
	 * @return string filename
	 */
	public function getName(){
		if ($this->file)
			return $this->file->getName();
	}

	/**
	 * Internal function that checks if server's may sizes match the
	 * object's maximum size for uploads
	 */
	private function checkServerSettings(){
		$postSize = $this->toBytes(ini_get('post_max_size'));
		$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
		if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
			$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
			die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
		}
	}

	/**
	 * Convert a given size with units to bytes
	 * @param string $str
	 */
	private function toBytes($str){
		$val = trim($str);
		$last = strtolower($str[strlen($str)-1]);
		switch($last) {
			case 'g': $val *= 1024;
			case 'm': $val *= 1024;
			case 'k': $val *= 1024;
		}
		return $val;
	}

	/**
	 * Handle the uploaded file
	 * @param string $uploadDirectory
	 * @param string $replaceOldFile=true
	 * @param User_User $objUser
	 * @returns array('success'=>true) or array('error'=>'error message')
	 */
	function handleUpload($uploadDirectory, $replaceOldFile = FALSE, $whatSave, $object = null) {
		if (!is_dir($uploadDirectory)) mkdir($uploadDirectory);
		
		if (!is_writable($uploadDirectory)){
			return array('error' => "Server error. Upload directory isn't writable.");
		}

		if (!$this->file){
			return array('error' => 'No files were uploaded.');
		}

		$size = $this->file->getSize();

		if ($size == 0) {
			return array('error' => 'File is empty');
		}

		if ($size > $this->sizeLimit) {
			return array('error' => 'File is too large');
		}

		$pathinfo = pathinfo($this->file->getName());
		$filename = $pathinfo['filename'];

		$ext = @$pathinfo['extension'];		// hide notices if extension is empty

		if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
			$these = implode(', ', $this->allowedExtensions);
			return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
		}

		$ext = ($ext == '') ? $ext : '.' . $ext;

		if(!$replaceOldFile){
			/// don't overwrite previous files that were uploaded
			while (file_exists($uploadDirectory . DIRECTORY_SEPARATOR . $filename . $ext)) {
				$filename .= rand(10, 99);
			}
		}
		
		$filename = 'tempAva';
		$this->uploadName = $filename . $ext;
		
		// Сохраняем временный файл
		if ($this->file->save($uploadDirectory . DIRECTORY_SEPARATOR . $this->uploadName)) {
			// Нарезаем варианты аватарок
			switch($whatSave) {
				case 'user-ava' :
					$filePath = $this->saveUserAvatar($this->uploadName, $ext, $object);
					break;
				case 'team-ava' :
					$filePath = $this->saveTeamAvatar($this->uploadName, $ext, $object);
					break;
			}
			return array('success'=>true, 'filePath' => $filePath);
		}
		else {
			return array('error'=> 'Could not save uploaded file.' .
					'The upload was cancelled, or server error encountered');
		}
	}
	
	public function saveUserAvatar($tempFileName, $ext, $objUser) {
		$uploadDirectory = IMAGES . '/essence/user/' . $objUser->id;
		$objImage = new Service_Image(array(
				'resizeType' => 'save_propotion',
				'availableExtensions' => array('jpg', 'png'),
				'throw' => true,
				'usePrefix' => true,
				'exception' => true
		));
			
		$filename = 'av' . $objUser->id  . '_' . rand(0, 100);
		$objImage->setGoalFolder('essence/user/' . $objUser->id . '/');
		$objImage->loadScrAsFile($uploadDirectory . '/' . $tempFileName);
		$objImage->setGoalName($filename);
		$objImage->setArrSizes(array(
				array('prefix' => 's', 'width' => 75, 'height' => 75),
				array('prefix' => 'm', 'width' => 100, 'height' => 100),
				array('prefix' => 'l', 'width' => 182, 'height' => 182),
		));
		$objImage->saveExistingFile();
		$objImage->save();
			
		// Удаляем файлы старого аватара
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . $objUser->getField('avatar_filename'));
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . 'l' . $objUser->getField('avatar_filename'));
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . 'm' . $objUser->getField('avatar_filename'));
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . 's' . $objUser->getField('avatar_filename'));
			
		// Записываем название нового
		$objUser->updateFields(array('avatar_filename' => $filename . $ext));
		
		return IMAGES_PATH . 'essence/user/' . $objUser->id . '/l' . $filename . $ext;
	}
	
	public function saveTeamAvatar($tempFileName, $ext, $objTeam) {
		$uploadDirectory = IMAGES . '/essence/team/' . $objTeam->id;
		$objImage = new Service_Image(array(
				'resizeType' => 'save_propotion',
				'availableExtensions' => array('jpg', 'png'),
				'throw' => true,
				'usePrefix' => true,
				'exception' => true
		));
			
		$filename = 'av' . $objTeam->id  . '_' . rand(0, 100);
		$objImage->setGoalFolder('essence/team/' . $objTeam->id . '/');
		$objImage->loadScrAsFile($uploadDirectory . '/' . $tempFileName);
		$objImage->setGoalName($filename);
		$objImage->setArrSizes(array(
				array('prefix' => 's', 'width' => 75, 'height' => 75),
				array('prefix' => 'm', 'width' => 100, 'height' => 100),
				array('prefix' => 'l', 'width' => 182, 'height' => 182),
		));
		$objImage->saveExistingFile();
		$objImage->save();
			
		// Удаляем файлы старого аватара
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . $objTeam->getField('avatar_filename'));
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . 'l' . $objTeam->getField('avatar_filename'));
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . 'm' . $objTeam->getField('avatar_filename'));
		@unlink($uploadDirectory . DIRECTORY_SEPARATOR . 's' . $objTeam->getField('avatar_filename'));
			
		// Записываем название нового
		$objTeam->updateFields(array('avatar_filename' => $filename . $ext));
	
		return IMAGES_PATH . 'essence/team/' . $objTeam->id . '/l' . $filename . $ext;
	}
}
?>